/*
 * ImageControl.java
 *
 * Created on 5 February 2007, 12:05
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package fasea.ui.utils;

import fasea.index.filehandler.DocumentType;
import fasea.utils.FileUtil;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.filechooser.FileSystemView;
import org.apache.commons.io.FilenameUtils;
import org.jpedal.PdfDecoder;

/**
 *
 * @author gvasil
 */
public class ImageControl {

    private ImageIcon STARS_ICON[];
    private Hashtable<DocumentType, ImageIcon> iconsTable;
    private ImageIcon INFO_ICON;
    private ImageIcon QUESTION_ICON;
    private ImageIcon WARNING_ICON;
    private ImageIcon ERROR_ICON;
    private ImageIcon SEARCH_ICON;
    private ImageIcon UPDATE_ICON;
    private Image TRAY_ICON;
    private Image SPINNER_ICON;
    private static final float DEFAULT_JPEG_QUALITY = 0.75f;
    private static final int DEFAULT_THUMBNAIL_HEIGHT = 150;
    private static int ICON_DIMENSION = 64;
    private static int IMAGE_DIMENSION = 80;
    private static ImageControl imageControl;

    private ImageControl() {
        ImageIcon icon = null;

        this.STARS_ICON = new ImageIcon[6];

        this.STARS_ICON[0] = new ImageIcon(getClass().getResource("/star-0.gif"));
        this.STARS_ICON[1] = new ImageIcon(getClass().getResource("/star-1.gif"));
        this.STARS_ICON[2] = new ImageIcon(getClass().getResource("/star-2.gif"));
        this.STARS_ICON[3] = new ImageIcon(getClass().getResource("/star-3.gif"));
        this.STARS_ICON[4] = new ImageIcon(getClass().getResource("/star-4.gif"));
        this.STARS_ICON[5] = new ImageIcon(getClass().getResource("/star-5.gif"));

        this.INFO_ICON = new ImageIcon(getClass().getResource("/gtk-dialog-info.png"));
        this.QUESTION_ICON = new ImageIcon(getClass().getResource("/gtk-dialog-question.png"));
        this.WARNING_ICON = new ImageIcon(getClass().getResource("/gtk-dialog-warning.png"));
        this.ERROR_ICON = new ImageIcon(getClass().getResource("/gtk-dialog-error.png"));
        this.SEARCH_ICON = new ImageIcon(getClass().getResource("/icon-search.png"));
        this.UPDATE_ICON = new ImageIcon(getClass().getResource("/update.png"));

        Toolkit toolkit = Toolkit.getDefaultToolkit();

        this.TRAY_ICON = toolkit.getImage(getClass().getResource("/16x16/puggle.png"));

        this.SPINNER_ICON = toolkit.getImage(getClass().getResource("/gnome-spinner.png"));

        this.iconsTable = new Hashtable<DocumentType, ImageIcon>();

        Image image = toolkit.getImage(getClass().getResource("/text-html.png"));
        image = image.getScaledInstance(ICON_DIMENSION, ICON_DIMENSION, BufferedImage.SCALE_SMOOTH);
        icon = new ImageIcon(image);
        this.iconsTable.put(DocumentType.HTML, icon);
        this.iconsTable.put(DocumentType.HTM, icon);

        image = toolkit.getImage(getClass().getResource("/text-spreadsheet.png"));
        image = image.getScaledInstance(ICON_DIMENSION, ICON_DIMENSION, BufferedImage.SCALE_SMOOTH);
        this.iconsTable.put(DocumentType.XLS, new ImageIcon(image));

        image = toolkit.getImage(getClass().getResource("/text-richtext.png"));
        image = image.getScaledInstance(ICON_DIMENSION, ICON_DIMENSION, BufferedImage.SCALE_SMOOTH);
        icon = new ImageIcon(image);
        this.iconsTable.put(DocumentType.RTF, icon);
        this.iconsTable.put(DocumentType.DOC, icon);

        image = toolkit.getImage(getClass().getResource("/text-x-generic.png"));
        image = image.getScaledInstance(ICON_DIMENSION, ICON_DIMENSION, BufferedImage.SCALE_SMOOTH);
        this.iconsTable.put(DocumentType.TXT, new ImageIcon(image));

        image = toolkit.getImage(getClass().getResource("/application-pdf.png"));
        image = image.getScaledInstance(ICON_DIMENSION, ICON_DIMENSION, BufferedImage.SCALE_SMOOTH);
        this.iconsTable.put(DocumentType.PDF, new ImageIcon(image));

        image = toolkit.getImage(getClass().getResource("/audio-x-mpeg.png"));
        image = image.getScaledInstance(ICON_DIMENSION, ICON_DIMENSION, BufferedImage.SCALE_SMOOTH);
        this.iconsTable.put(DocumentType.MP3, new ImageIcon(image));

        image = toolkit.getImage(getClass().getResource("/gnome-fs-directory.png"));
        image = image.getScaledInstance(ICON_DIMENSION, ICON_DIMENSION, BufferedImage.SCALE_SMOOTH);
        this.iconsTable.put(DocumentType.FOLDER, new ImageIcon(image));

        image = toolkit.getImage(getClass().getResource("/application-x-compress.png"));
        image = image.getScaledInstance(ICON_DIMENSION, ICON_DIMENSION, BufferedImage.SCALE_SMOOTH);
        icon = new ImageIcon(image);
        this.iconsTable.put(DocumentType.ZIP, icon);
        this.iconsTable.put(DocumentType.RAR, icon);

        image = toolkit.getImage(getClass().getResource("/unknown.png"));
        image = image.getScaledInstance(ICON_DIMENSION, ICON_DIMENSION, BufferedImage.SCALE_SMOOTH);
        this.iconsTable.put(DocumentType.DEFAULT, new ImageIcon(image));
    }

    public static synchronized ImageControl getImageControl() {
        if (imageControl == null) {
            imageControl = new ImageControl();
        }

        return imageControl;
    }

    public ImageIcon getStarsIcon(int number) {
        return STARS_ICON[number];
    }

    public ImageIcon getWarningIcon() {
        return this.WARNING_ICON;
    }

    public ImageIcon getInfoIcon() {
        return this.INFO_ICON;
    }

    public ImageIcon getUpdateIcon() {
        return this.UPDATE_ICON;
    }

    public ImageIcon getQuestionIcon() {
        return this.QUESTION_ICON;
    }

    public ImageIcon getErrorIcon() {
        return this.ERROR_ICON;
    }

    public Image getTrayIcon() {
        return this.TRAY_ICON;
    }

    public Image getSpinnerIcon() {
        return this.SPINNER_ICON;
    }

    public ImageIcon getSpinnerImageIcon() {
        return new ImageIcon(this.SPINNER_ICON);
    }

    /**
     * A method that scales a Buffered image and takes the required height as a
     * refference point*
     */
    public BufferedImage getScaledCover(BufferedImage image)
            throws java.lang.Exception {

        int width = image.getWidth();
        int height = image.getHeight();

        int max = Math.max(width, height);
        int z = max / IMAGE_DIMENSION;

        Image scaledImage = image.getScaledInstance(width / z, height / z,
                BufferedImage.SCALE_SMOOTH);

        BufferedImage outImage = new BufferedImage(width / z, height / z,
                BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = (Graphics2D) outImage.createGraphics();
        g2.drawImage(scaledImage, 0, 0, null);

        scaledImage = null;
        return outImage;
    }

    public Icon getThumbnail(DocumentType type){
        Icon icon = iconsTable.get(type);
        if(icon == null){
            icon = iconsTable.get(DocumentType.DEFAULT); 
        }
        return icon;
    }

    public byte[] createImageThumbnail(BufferedImage sourceImage) {
        ByteArrayOutputStream baos = null;
        byte[] bytes = null;
        try {
            int width = sourceImage.getWidth();
            int height = sourceImage.getHeight();
            int max = Math.max(width, height);
            int z = max / DEFAULT_THUMBNAIL_HEIGHT;
            if (z == 0) {
                z = 1;
            }
            BufferedImage scaledImage = scale(sourceImage, width / z, height / z);
            baos = new ByteArrayOutputStream();
            ImageIO.write(scaledImage, "jpg", baos);
            baos.flush();
            bytes = baos.toByteArray();
        } catch (IOException ex) {
            Logger.getLogger(ImageControl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException ex) {
                    Logger.getLogger(ImageControl.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        return bytes;
    }

    private BufferedImage scale(BufferedImage source, int w, int h) {
        BufferedImage bi = getCompatibleImage(w, h);
        Graphics2D g2d = bi.createGraphics();
        double xScale = (double) w / source.getWidth();
        double yScale = (double) h / source.getHeight();
        AffineTransform at = AffineTransform.getScaleInstance(xScale, yScale);
        g2d.drawRenderedImage(source, at);
        g2d.dispose();
        return bi;
    }

    private BufferedImage getCompatibleImage(int w, int h) {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        GraphicsConfiguration gc = gd.getDefaultConfiguration();
        BufferedImage image = gc.createCompatibleImage(w, h);
        return image;
    }

    public byte[] toByteArray(BufferedImage img) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        Iterator writers = ImageIO.getImageWritersByMIMEType("image/jpeg");
        ImageWriter imgWriter = (ImageWriter) writers.next();

        ImageOutputStream imgStream = ImageIO.createImageOutputStream(output);
        imgWriter.setOutput(imgStream);

        imgWriter.write(img);

        byte[] data = null;

        data = output.toByteArray();
        output.close();

        return data;
    }
}
